//State machine for talking to accelerometer chip: BMA180 made by Bosch
//Sensortech
//Set at +- 1g acceleration
//
//Returns X, Y, Z acceleration values to the avalon bus
//
module accel (
             input wire reset_n, 
             input wire CLOCK_50, 
		     inout wire I2C_SDAT,
             input wire A_INT,
		     output wire I2C_SCLK,
		     output wire [7:0]LED
			);

reg [31:0] counter = 0;
reg [31:0] counter2 = 0;
wire CLOCK_2;

always @(posedge CLOCK_50)
begin

    counter <= counter + 1'b1;
end

always @(posedge CLOCK_2)
begin

    counter2 <= counter2 + 1'b1;
end


pll pll_inst (.areset (1'b0),
              .inclk0 (CLOCK_50), 
              .c0     (CLOCK_2)
             );

assign LED[0] = counter [26];
assign LED[1] = counter2 [24];
assign LED[2] = A_INT;

assign I2C_SCLK = sclk_q;
assign I2C_SDAT = sdat_q;

////////////////////////////////////////////////////////////////////////////////
//FSM I2C LOGIC///////////
////////////////////////////////////////////////////////////////////////////////

reg sdat_d;
reg sclk_d;
reg sdat_q;
reg sclk_q;

//State 
parameter IDLE = 5'd0;
parameter START = 5'd1;
parameter SLAVE_ADDR_WR = 5'd2;
parameter WRITE_BYTE = 5'd3;
parameter WRITE_ONE_0 = 5'd4;
parameter WRITE_ONE_1 = 5'd5;
parameter WRITE_ONE_2 = 5'd6;
parameter WRITE_ONE_3 = 5'd7;
parameter WRITE_ZERO_0 = 5'd8;
parameter WRITE_ZERO_1 = 5'd9;
parameter WRITE_ZERO_2 = 5'd10;
parameter WRITE_ZERO_3 = 5'd11;
parameter ACK_PULSE_0 = 5'd12;
parameter ACK_PULSE_1 = 5'd13;
parameter REGISTER_ADDR_WR = 5'd14;



reg [5:0] i2c_state_c = IDLE;
reg [5:0] i2c_state_n = IDLE;

reg [5:0] state_issuing_wr_d = 0; 
reg [5:0] state_issuing_wr_q = 0; 
reg [3:0] bit_number_d = 0;
reg [3:0] bit_number_q = 0;
reg [7:0] byte_d = 0;
reg [7:0] byte_q = 0;
reg write_done_d = 0;
reg write_done_q = 0;
reg start_d = 0;
reg start_q = 0;
 
always@(posedge CLOCK_2 or negedge reset_n)
begin
    if(!reset_n)
	begin
        i2c_state_c <= IDLE;
        sdat_q <= 1'b1;
        sclk_q <= 1'b1;
        start_q <= 0;
    end
    else 
    begin
        start_q <= 1;
        i2c_state_c <= i2c_state_n;
        sdat_q <= sdat_d;
        sclk_q <= sclk_d;

        state_issuing_wr_q <= state_issuing_wr_d;
        bit_number_q <= bit_number_d;
        byte_q <= byte_d;
        write_done_q <= write_done_d;
    end
end
	
always @(*)
begin
	i2c_state_n = IDLE;
	sdat_d = 1'bz;
	sclk_d = 1'b1;

    state_issuing_wr_d = 0; 
    bit_number_d = 0;
    byte_d = 0;

    write_done_d = 0;
    
 
    case (i2c_state_c)
        IDLE: 
        begin
            sdat_d = 1'b1;
            sclk_d = 1'b1;
            if (start_q) i2c_state_n = START;
            else i2c_state_n = IDLE;
        end
        START:
        begin
            sdat_d = sdat_q;
            sclk_d = sclk_q;

            sdat_d = 0;
            i2c_state_n = SLAVE_ADDR_WR;
        end
        SLAVE_ADDR_WR:
        begin
            sdat_d = sdat_q;
            sclk_d = sclk_q;


            //slave adress of the acceleromoeter chip
            byte_d = 8'hFA;
            //
            bit_number_d = 4'd8;

            state_issuing_wr_d = SLAVE_ADDR_WR;
            if (write_done_q) i2c_state_n = REGISTER_ADDR_WR;
            else i2c_state_n = WRITE_BYTE;
        end
        WRITE_BYTE:
        begin
            state_issuing_wr_d = state_issuing_wr_q; 
            bit_number_d = bit_number_q;
            byte_d = byte_q;
            sdat_d = sdat_q;
            sclk_d = sclk_q;
            if (bit_number_q == 0) i2c_state_n = ACK_PULSE_0;
            else
            begin
                if (byte_q[bit_number_q-1'b1] == 1'b1) i2c_state_n = WRITE_ONE_0;
                else i2c_state_n = WRITE_ZERO_0;
            end
            
        end
        WRITE_ONE_0:
        begin
            state_issuing_wr_d = state_issuing_wr_q; 
            bit_number_d = bit_number_q;
            byte_d = byte_q;
            sdat_d = sdat_q;
            sclk_d = sclk_q;

            sclk_d = 0;
            i2c_state_n = WRITE_ONE_1;
        end 
        WRITE_ONE_1:
        begin
            state_issuing_wr_d = state_issuing_wr_q; 
            bit_number_d = bit_number_q;
            byte_d = byte_q;
            sdat_d = sdat_q;
            sclk_d = sclk_q;

            //actual bit
            sdat_d = 1;
            i2c_state_n = WRITE_ONE_2;
        end 
        WRITE_ONE_2:
        begin
            state_issuing_wr_d = state_issuing_wr_q; 
            bit_number_d = bit_number_q;
            byte_d = byte_q;
            sdat_d = sdat_q;
            sclk_d = sclk_q;

            sclk_d = 1;
            i2c_state_n = WRITE_ONE_3;
        end 
        WRITE_ONE_3:
        begin
            state_issuing_wr_d = state_issuing_wr_q; 
            bit_number_d = bit_number_q;
            byte_d = byte_q;
            sdat_d = sdat_q;
            sclk_d = sclk_q;

            sclk_d = 0;

            bit_number_d = bit_number_q - 1'b1;
            i2c_state_n = WRITE_BYTE;
        end 
        WRITE_ZERO_0:
        begin
            state_issuing_wr_d = state_issuing_wr_q; 
            bit_number_d = bit_number_q;
            byte_d = byte_q;
            sdat_d = sdat_q;
            sclk_d = sclk_q;

            sclk_d = 0;
            i2c_state_n = WRITE_ZERO_1;
        end 
        WRITE_ZERO_1:
        begin
            state_issuing_wr_d = state_issuing_wr_q; 
            bit_number_d = bit_number_q;
            byte_d = byte_q;
            sdat_d = sdat_q;
            sclk_d = sclk_q;

            //actual bit
            sdat_d = 0;
            i2c_state_n = WRITE_ZERO_2;
        end 
        WRITE_ZERO_2:
        begin
            state_issuing_wr_d = state_issuing_wr_q; 
            bit_number_d = bit_number_q;
            byte_d = byte_q;
            sdat_d = sdat_q;
            sclk_d = sclk_q;

            sclk_d = 1;
            i2c_state_n = WRITE_ZERO_3;
        end 
        WRITE_ZERO_3:
        begin
            state_issuing_wr_d = state_issuing_wr_q; 
            bit_number_d = bit_number_q;
            byte_d = byte_q;
            sdat_d = sdat_q;
            sclk_d = sclk_q;

            sclk_d = 0;

            bit_number_d = bit_number_q - 1'b1;
            i2c_state_n = WRITE_BYTE;
        end 
        ACK_PULSE_0:
        begin
            state_issuing_wr_d = state_issuing_wr_q; 
            sclk_d = sclk_q;
            if (I2C_SDAT == 0)
            begin
                sclk_d = 1;
                i2c_state_n = ACK_PULSE_1;
            end
            else i2c_state_n = ACK_PULSE_0;
        end
        ACK_PULSE_1:
        begin
            //state_issuing_wr_d = state_issuing_wr_q; 
            sclk_d = sclk_q;

            sclk_d = 0;

            write_done_d = 1;
            i2c_state_n = state_issuing_wr_q;
        end
        REGISTER_ADDR_WR:
        begin
           i2c_state_n = REGISTER_ADDR_WR;
        end
        
        

    endcase
end






endmodule


